package com.cskaoyan.javase.oop1._2reference;

/**
 * 重新认识引用数据类型
 * 我们第一次认识和了解引用数据类型是在数组这一章节
 * 我们通过JVM内存模型图和数组的初始化过程，知道：
 * 一个引用数据类型变量，分为两个部分：
 *      1.在栈上创建引用，它是一个局部变量。
 *      2.在堆上开辟空间，创建对象。
 * 栈上的引用通过存储堆上对象的地址和对象产生联系。
 * 对象是引用数据类型的实质，但我们只能通过栈上引用间接访问堆上对象。
 *
 * 现在，我们已经学习过对象与类的知识点了，是时候进一步或者换一个角度去了解引用数据类型了。
 *
 * 引用数据类型的全新理解
 *
 * 像数组那样理解引用数据类型，虽然看到了引用数据类型的实质，但也把基本数据类型和引用数据类型完全割裂了。
 * 这两种数据类型当然不可能是完全没有关系的了！
 * 所以，我们需要让它们重新产生联系起来！
 *
 * 先回顾一下，在Java基础语法部分，我们给出的数据类型的概念/定义：
 *
 * 数据类型：
 * 表示的是一组数据的集合，和基于该数据集合的一组合法操作。
 * 这个定义套在基本数据类型上，实在再合适不过了。
 * 比如int类型，它的取值范围是固定的，有限的，能够做的操作（加减乘除等）也是被限制的。
 * 那么这个定义能不能套在引用数据类型中呢？能否用数据类型的概念来统一基本数据类型和引用数据类型呢？
 * 接下来我们需要分析一下，这个问题。
 * 在上一节类的定义中，类中的成员包括：
 *          1.成员变量 = 数据
 *          2.成员方法 = 操作
 * 成员变量本质上就是数据，成员方法本质上就是操作，那么假设做以下类比：
 * 数据的集合： 类中成员变量的集合
 * 操作的集合： 类中成员方法的集合
 * 定义了一个类,就等于定义了 数据 + 操作
 *
 * 于是，就可以做出以下总结：
 * 一个类的定义，实际上就是定义了一种全新的数据类型，一种自定义的数据类型。
 * 这种完全不同于基本数据类型的数据类型，我们称之为"引用数据类型"。
 * 注：当然引用数据类型不仅仅包括类，但大体上上述说法是没问题的。
 *
 * 引用数据类型/基本数据类型的不同点
 * 当我们在程序中使用一个基本数据类型时，由于基本数据类型是JVM当中已经预先定义好的数据类型（所以基本数据类型叫"内置数据类型"）
 * JVM可以清楚的知道这个基本数据类型变量在内存中的存储方式（占用空间大小、结构等等），JVM能够正常开辟空间，正常给变量初始化赋值。
 *
 * 但是类这种引用数据类型，并不是内置数据类型，而是我们自定义的数据类型。
 * 现在我们要根据一个类来创建它的对象，要让JVM帮助我们开辟空间创建引用和对象，JVM怎么知道到底要创建什么呢？难道它未卜先知吗？
 * 显然是不可能的，某个类在一开始并不被JVM"认识"——它不知道类中有什么，必然不可能做任何操作。
 * 所以在对某个类做任何操作之前，都需要让JVM来"认识"这个类型。比如该类中有什么成员变量,有什么方法等等.
 * 在Java中，把JVM"认识/了解"一个类的过程，称之为类加载(class load)。
 *
 * 关于类加载：
 *      1.类加载的具体过程，我们后面会详细学习。
 *          这里我们先不用了解它的详细过程。
 *      2.类加载是JVM认识了解一个类型的过程,JVM会将某个类的class字节码文件
 *          通过I/O流的形式读取进JVM内存的方法区中
 *          然后通过一系列的操作,JVM完成类加载的过程,才能够完成和该类相关的操作
 *
 * 上述第2句话非常重要,有以下细节:
 *      1.类加载是通过I/O的形式读取硬盘文件实现的.
 *          I/O流读取文件最大的问题就是慢,很慢,非常影响程序的执行效率
 *          所以这就导致,JVM在类加载某个类的时候,是"懒加载"的:
 *          只有当碰到"迫不得已,不类加载一个类不行了"这种情况时,才会进行类加载
 *
 *      在Java当中把"迫不得已,不类加载一个类不行了"的情况,称之为"类加载的时机"
 *      代码中一旦出现"类加载的时机"就一定会,先完成该类的类加载,再去执行它.
 *
 *      目前已经学习过的类加载的时机:
 *          a.new对象,一旦想创建某个类的对象,就必须先类加载该类
 *          b.启动main方法.在某个类的main方法启动之前,必须先类加载这个类.
 *
 *      2.类加载最重要的特点是,在一次程序的运行期间,某个类最多类加载一次
 *          比如一个类通过某种类加载的时机触发了类加载
 *          执行到后面,如果又碰到了类加载的时机,就不会再次类加载了!
 *
 * @since 16:16
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    // 启动main方法,Demo类已经类加载了!而且是类加载Demo在前,启动main方法在后
    public static void main(String[] args) {
        // 创建Teacher对象
        Teacher t = new Teacher();
        Teacher t2 = new Teacher();

        // 这里还会类加载Demo吗? 显然是不会的
        Demo d = new Demo();
    }
}

class Teacher {
    double salary;
    double bonus;
}